local love = require 'love'
local deckTriangle = require('components.deck-triangle')
local discardButton = require('components.discard-button')
local gift = require('components.gift')
local guide = require('components.guide')
local infoBar = require('components.info-bar')
local instructionsButton = require('components.instructions-button')
local playButton = require('components.play-button')
local reorderButton = require('components.reorder-button')
local restartButton = require('components.restart-button')
local turns = require('components.turns')
local bounceText = require('controller.bounce-text')
local handCardsController = require('controller.handcards-controller')
local healthBarController = require('controller.healthbar-controller')
local imageController = require('controller.image-controller')
local continue = require('scenes.continue')
local cover = require('scenes.cover')
local deck = require('scenes.deck')
local instructions = require("scenes.instructions")
local settle = require("scenes.settle")
local score = require('utils.score')
local quit = love.event.quit

-- 按照 scene > playStep > button / nowClick 显示场景及鼠标控制分区等;
-- mousepressed 中用 button 控制; mousereleased 中用 nowClick 控制, nowClick 为 0 则不走 mousereleased
local scene = 1 -- 1：封面；2：出牌页面；3：结算页面；4：说明页面；5：牌库页面；6: 继续页面; 7: 致谢页面;
local playStep = 1 -- 1：开始/继续；2：发牌；3：指南；4：游玩；5：结算；6：重来; 7: 致谢;
-- 每一个 scene & playStep 相对独立;
-- s2p2: 1: Play; 2: Instructions; 3: Deck;
-- s2p4: 1: Play; 2: Discard; 3: Deck; 4: Instructions; 5: Restart; 6: Handcards;
-- s4: 1: Instructions
local nowClick = 0  -- 默认不走 released
local countHandCards = 8 -- 手牌数
local playableCardCount = 5 -- 可出牌数
local maxHandCards = 9 -- 最大手牌数
local drawnCards = {}
local handCards = {}
local thisTurnSelectedCards = {}
local retained = {}
local selectedHash = {}
local totalNum = 0
local thisResult = ""
local thisTurnType = ""
local thisTurnScore = 0
local healthBarText = ""
local changeHandCards = false
local turn = 1 -- 回合数
local match = 1 -- 游戏场数
local totalMatches = 7
local matchFinished = false
local settlement = 1 -- 1：胜利；2：失败
local lastClickTime = 0
local clickInterval = 0.3  -- 允许点击的最小间隔（秒）
local guideActive = true
local guideGift = {"heartsDiamonds"}
local changedThisTurnSelectedCards = {}

local currentGift = {"heartsDiamonds", "clubsspades", "addmaxhandcards"}

function love.load()
    continue.init()
    cover.init()
    imageController.init()
    playButton.init()
    deck.init()
    deckTriangle.init()
    bounceText.init()
    instructionsButton.init()
    instructions.init()
    discardButton.init()
    restartButton.init()
    reorderButton.init()
    handCardsController.init(maxHandCards)
    healthBarController.init()
    infoBar.init()
    gift.init()
    guide.init()
    turns.init()
    settle.init()
    infoBar.addMessage("欢迎游玩")
end

local function resetMatch()
    turn = 1
    deck.reset()
    drawnCards = {}
    thisTurnSelectedCards = {}
    handCardsController.resetThisTurnSelectedCards()
    healthBarController.reset()
end

function love.update(dt)
    -- local mem = collectgarbage("count")
    -- print("内存使用: " .. mem .. " KB")
    if scene == 1 then
        if playStep == 1 or playStep == 6 then
            cover.update(dt)
        end
    elseif scene == 2 then
        if playStep == 4 then
            restartButton.update(dt)
            healthBarController.update(dt)
        end
    elseif scene == 4 then
        instructions.update(dt)
    elseif scene == 5 then
        bounceText.update(dt)
    elseif scene == 6 then
        continue.update(dt)
    end
end

function love.draw()
    if scene == 1 then
        if playStep == 1 or playStep == 6 then
            cover.drawCover()
            playButton.drawPlayButton(playStep, match)
        end
    elseif scene == 2 then
        if playStep == 2 then
            imageController.drawStart()
            deckTriangle.drawDeckTriangle()
            instructionsButton.drawButton()
            playButton.drawPlayButton(playStep, match)
        elseif playStep == 3 then
            imageController.drawStart()
            handCardsController.drawHnadCards(drawnCards, changeHandCards)
            changeHandCards = false
            handCards = handCardsController.getHandCards()
            healthBarController.drawBar()
            playButton.drawPlayButton(playStep, match)
            discardButton.drawButton()
            reorderButton.drawButton()
            restartButton.drawButton()
            infoBar.drawInfoBar()
            turns.drawTurn(turn)
            gift.drawGift(guideGift)
            deckTriangle.drawDeckTriangle()
            instructionsButton.drawButton()
            guide.drawGuide()
        elseif playStep == 4 then
            imageController.drawMonster(match)
            imageController.drawDesk()
            infoBar.drawInfoBar()
            handCardsController.drawHnadCards(drawnCards, changeHandCards)
            changeHandCards = false
            handCards = handCardsController.getHandCards()
            healthBarController.drawBar()
            playButton.drawPlayButton(playStep, match)
            discardButton.drawButton()
            reorderButton.drawButton()
            restartButton.drawButton()
            turns.drawTurn(turn)
            gift.drawGift(currentGift)
            deckTriangle.drawDeckTriangle()
            instructionsButton.drawButton()
            handCardsController.drawSelect()

            if matchFinished then
                settlement = 1
                infoBar.addMessage("第 " .. match .. " 局胜利")
                scene = 3
                playStep = 5
                matchFinished = false
            elseif #drawnCards == 0 then
                settlement = 2
                infoBar.addMessage("失败, 牌库已空")
                scene = 3
                playStep = 5
            end
        end
    elseif scene == 3 then
        settle.drawSettlement(settlement)
    elseif scene == 4 then
        instructions.draw()
    elseif scene == 5 then
        deck.drawCards()
        bounceText.drawBounceText()
    elseif scene == 6 then
        continue.draw(match)
    elseif scene == 7 then
        imageController.drawCredits()
    end
end

function love.mousepressed(x, y, button) -- 没有按钮的场景，以及排序 pressed 即判断；其余在 released 里判断
    -- 防止鼠标连击
    local currentTime = love.timer.getTime() -- 获取当前时间
    if currentTime - lastClickTime < clickInterval then return end
    lastClickTime = currentTime -- 更新上次点击时间

    if scene == 1 then
        if playStep == 1 then
            if button == 1 then
                if playButton.inArea(x, y) then
                    playButton.isPressed()
                    nowClick = 1
                end
            end
        elseif playStep == 6 then
            if button == 1 then
                if playButton.inArea(x, y) then
                    playButton.isPressed()
                    nowClick = 1
                end
            end
        end
    elseif scene == 2 then
        if playStep == 2 then
            if button == 1 then
                if playButton.inArea(x, y) then
                    playButton.isPressed()
                    nowClick = 1
                elseif instructionsButton.inArea(x, y) then
                    instructionsButton.isPressed()
                    nowClick = 2
                elseif deckTriangle.inArea(x, y) then
                    deckTriangle.isPressed()
                    nowClick = 3
                end
            end
        elseif playStep == 3 then
            if button == 1 then
                if guide.getGuideFinished() then
                    playStep = 4
                elseif guide.inAreaSkip(x) then
                    playStep = 4
                else
                    guide.addStep()
                end
            end
        elseif playStep == 4 then
            if button == 1 then
                if reorderButton.inArea(x, y) then
                    -- 切换排序
                    reorderButton.isPressed()
                    handCardsController.toggleShowIcon()

                    -- 取消被选中的牌
                    thisTurnSelectedCards = {}
                    handCardsController.resetThisTurnSelectedCards()
                    changeHandCards = true
                    if reorderButton.getShowIcon() then
                        infoBar.addMessage("已按花色排序")
                    else
                        infoBar.addMessage("已从小到大排序")
                    end
                elseif playButton.inArea(x, y) then
                    playButton.isPressed()
                    nowClick = 1
                elseif discardButton.inArea(x, y) then
                    discardButton.isPressed()
                    nowClick = 2
                elseif deckTriangle.inArea(x, y) then
                    deckTriangle.isPressed()
                    nowClick = 3
                elseif instructionsButton.inArea(x, y) then
                    instructionsButton.isPressed()
                    nowClick = 4
                elseif restartButton.inArea(x, y) then
                    restartButton.isPressed()
                    nowClick = 5
                elseif handCardsController.inArea(y) then
                    handCardsController.isPressed(x, y)
                    nowClick = 6
                end
            end
        end
    elseif scene == 3 then
        if playStep == 5 then
            if button == 1 then
                if settlement == 1 then
                    resetMatch()
                    if match == totalMatches then
                        match = 1
                        settle.reset()
                        scene = 7
                        playStep = 7
                    else
                        match = match + 1
                        -- 顺延到下一局
                        scene = 6
                        playStep = 1
                    end
                elseif settlement == 2 then
                    scene = 1
                    playStep = 6
                    -- 重置在重来按钮下
                end
            end
        end
    elseif scene == 4 then
        if button == 1 then
            instructions.mousepressed(x, y)
            nowClick = 1
        elseif button == 2 then
            scene = 2
            instructions.deactive()
        end
    elseif scene == 5 then
        scene = 2
        bounceText.deactive()
    elseif scene == 6 then
        if button == 1 then
            if continue.inArea(x, y) then
                scene = 2
                playStep = 2
            end
        end
    elseif scene == 7 then
        if playStep == 7 then
            scene = 1
            playStep = 1
        end
    end
end

function love.mousereleased(x, y)
    if nowClick == 0 then return end
    if scene == 1 then
        if playStep == 1 then
            if nowClick == 1 then
                playButton.isReleased()
                if playButton.inArea(x, y) then
                    scene = 2
                    playStep = 2
                end
            end
        elseif playStep == 6 then
            if nowClick == 1 then
                playButton.isReleased()
                -- 重来按钮
                if playButton.inArea(x, y) then
                    resetMatch()
                    playStep = 2
                    scene = 2
                    infoBar.addMessage("欢迎来到新的一局")
                end
            end
        end
    elseif scene == 2 then
        if playStep == 2 then
            if nowClick == 1 then
                playButton.isReleased()
                if playButton.inArea(x, y) then
                    -- 第一次发牌
                    drawnCards = deck.deal(gift.changeNum(countHandCards, currentGift), retained)
                    changeHandCards = true
                    totalNum = deck.getRemainingCardCount()
                    infoBar.addMessage("第 " .. turn .. " 回合")
                    infoBar.addMessage("发牌完毕，牌库剩余 " .. totalNum .. " 张")
                    if guideActive then
                        guideActive = false
                        playStep = 3
                    else
                        playStep = 4
                    end
                end
            elseif nowClick == 2 then
                instructionsButton.isReleased()
                if instructionsButton.inArea(x, y) then
                    scene = 4
                end
            elseif nowClick == 3 then
                deckTriangle.isReleased()
                if deckTriangle.inArea(x, y) then
                    scene = 5
                    bounceText.active()
                end
            end
        elseif playStep == 4 then
            if nowClick == 1 then
                playButton.isReleased()
                if playButton.inArea(x, y) then
                    -- 出牌
                    if thisTurnSelectedCards == nil or #thisTurnSelectedCards == 0 then
                        infoBar.addMessage("请选择要出手的牌")
                    elseif #thisTurnSelectedCards > playableCardCount then -- 限制出牌数
                        infoBar.addMessage("超出出牌数限制")
                    else
                        -- 出牌信息
                        local cardNames = {}
                        for i, card in pairs(thisTurnSelectedCards) do
                            cardNames[i] = deck.getSuitChineseCharacter(card) .. " " .. deck.getRank(card)
                        end
                        thisResult = "打出了 " .. table.concat(cardNames, ", ")
                        infoBar.addMessage(thisResult, turn)

                        -- 从 handCards 中筛选出不在 thisTurnSelectedCards 里的元素并添加到 retained：
                        -- 先将 thisTurnSelectedCards 转换为哈希表，提升查找速度
                        retained = {}
                        for _, card in ipairs(thisTurnSelectedCards) do
                            selectedHash[card] = true
                        end
                        -- 筛选未选中的卡片
                        for _, handCard in ipairs(handCards) do
                            if not selectedHash[handCard.number] then
                                table.insert(retained, handCard.number)
                            end
                        end
                        selectedHash = {}
                        drawnCards = deck.deal(#thisTurnSelectedCards, retained)
                        changeHandCards = true
                        retained = {}
                        totalNum = deck.getRemainingCardCount()
                        changedThisTurnSelectedCards = gift.changeType(thisTurnSelectedCards, currentGift)
                        thisTurnType = score.typeChineseCharacters(changedThisTurnSelectedCards)
                        thisTurnScore = score.getReadScore()
                        infoBar.addMessage("组成<" .. thisTurnType .. ">, 造成 " .. thisTurnScore .. " 点伤害!")
                        matchFinished = healthBarController.add(thisTurnScore)
                        settle.settle(score.type(changedThisTurnSelectedCards), thisTurnScore, matchFinished)
                        turn = turn + 1
                        healthBarText = thisTurnType .. "! - " .. thisTurnScore
                        healthBarController.setText(healthBarText)
                        thisTurnSelectedCards = {}
                        handCardsController.resetThisTurnSelectedCards()
                    end
                end
            elseif nowClick == 2 then
                discardButton.isReleased()
                if discardButton.inArea(x, y) then
                    if thisTurnSelectedCards == nil or #thisTurnSelectedCards == 0 then
                        infoBar.addMessage("请选择要丢弃的牌")
                    elseif thisTurnSelectedCards == nil or #thisTurnSelectedCards > playableCardCount then -- 限制弃牌数
                        infoBar.addMessage("超出出牌数限制")
                    else
                        -- 弃牌信息
                        local cardNames = {}
                        for i, card in pairs(thisTurnSelectedCards) do
                            cardNames[i] = deck.getSuitChineseCharacter(card) .. " " .. deck.getRank(card)
                        end
                        thisResult = "丢弃了 " .. table.concat(cardNames, ", ")
                        infoBar.addMessage(thisResult, turn)

                        -- 从 handCards 中筛选出不在 thisTurnSelectedCards 里的元素并添加到 retained：
                        -- 先将 thisTurnSelectedCards 转换为哈希表，提升查找速度
                        retained = {}
                        for _, card in ipairs(thisTurnSelectedCards) do
                            selectedHash[card] = true
                        end
                        -- 筛选未选中的卡片
                        for _, handCard in ipairs(handCards) do
                            if not selectedHash[handCard.number] then
                                table.insert(retained, handCard.number)
                            end
                        end
                        selectedHash = {}
                        drawnCards = deck.deal(#thisTurnSelectedCards, retained)
                        changeHandCards = true
                        retained = {}

                        totalNum = deck.getRemainingCardCount()
                        infoBar.addMessage("牌库剩余 " .. totalNum .. " 张")
                        thisTurnSelectedCards = {}
                        handCardsController.resetThisTurnSelectedCards()
                    end
                end
            elseif nowClick == 3 then
                deckTriangle.isReleased()
                if deckTriangle.inArea(x, y) then
                    scene = 5
                    bounceText.active()
                end
            elseif nowClick == 4 then
                instructionsButton.isReleased()
                if instructionsButton.inArea(x, y) then
                    scene = 4
                end
            elseif nowClick == 5 then
                restartButton.isReleased()
                if restartButton.inArea(x, y) then
                    match = 1
                    settle.reset()
                    resetMatch()
                    playStep = 2
                    scene = 2
                    infoBar.addMessage("欢迎来到新的一局")
                end
            elseif nowClick == 6 then
                thisTurnSelectedCards = handCardsController.isReleased()
                if thisTurnSelectedCards ~= nil and #thisTurnSelectedCards > playableCardCount then
                    infoBar.addMessage("最多选择 " .. playableCardCount .. " 张")
                end
            end
        end
    elseif scene == 4 then
        if nowClick == 1 then
            instructions.mousereleased()
        end
    end

    nowClick = 0
end

function love.keypressed(key)
    if scene == 2 then
        if playStep == 4 then
            infoBar.keypressed(key)
        end
    elseif scene == 4 then
        instructions.keypressed(key)
    elseif scene == 5 then
        scene = 2
        bounceText.deactive()
    end

    if key == 'escape' then
        quit()
    end
end

function love.mousemoved(x, y)
    if scene == 1 then
        if playStep == 1 or playStep == 6 then
            if playButton.inArea(x, y) then
                playButton.isHovered(true)
            else
                playButton.isHovered(false)
            end
        end
    elseif scene == 2 then
        if playStep == 2 then
            if playButton.inArea(x, y) then
                playButton.isHovered(true)
                instructionsButton.isHovered(false)
                deckTriangle.isHovered(false)
            elseif instructionsButton.inArea(x, y) then
                playButton.isHovered(false)
                instructionsButton.isHovered(true)
                deckTriangle.isHovered(false)
            elseif deckTriangle.inArea(x, y) then
                playButton.isHovered(false)
                instructionsButton.isHovered(false)
                deckTriangle.isHovered(true)
            else
                playButton.isHovered(false)
                instructionsButton.isHovered(false)
                deckTriangle.isHovered(false)
            end
        elseif playStep == 3 then
            guide.isHovered(x)
        elseif playStep == 4 then
            if nowClick == 6 then
                handCardsController.isMoved(x, y)
            elseif infoBar.inArea(x, y) then
                infoBar.active()
                reorderButton.isHovered(false)
                playButton.isHovered(false)
                discardButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            elseif reorderButton.inArea(x, y) then
                infoBar.deactive()
                reorderButton.isHovered(true)
                playButton.isHovered(false)
                discardButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            elseif playButton.inArea(x, y) then
                infoBar.deactive()
                reorderButton.isHovered(false)
                playButton.isHovered(true)
                discardButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            elseif discardButton.inArea(x, y) then
                infoBar.deactive()
                reorderButton.isHovered(false)
                playButton.isHovered(false)
                discardButton.isHovered(true)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            elseif deckTriangle.inArea(x, y) then
                infoBar.deactive()
                reorderButton.isHovered(false)
                playButton.isHovered(false)
                discardButton.isHovered(false)
                deckTriangle.isHovered(true)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            elseif instructionsButton.inArea(x, y) then
                infoBar.deactive()
                reorderButton.isHovered(false)
                playButton.isHovered(false)
                discardButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(true)
                restartButton.isHovered(false)
            elseif restartButton.inArea(x, y) then
                infoBar.deactive()
                playButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                discardButton.isHovered(false)
                reorderButton.isHovered(false)
                restartButton.isHovered(true)
            else
                infoBar.deactive()
                reorderButton.isHovered(false)
                playButton.isHovered(false)
                discardButton.isHovered(false)
                deckTriangle.isHovered(false)
                instructionsButton.isHovered(false)
                restartButton.isHovered(false)
            end
        end
    elseif scene == 4 then
        instructions.mousemoved(y)
    end
end

function love.wheelmoved(x, y)
    if scene == 4 then
        instructions.wheelmoved(y)
    end
end